package queue

import "sync"

const Done = -1

type Queue interface {
	Add(interface{})
	Poll() interface{}
	Size() int
	IsEmpty() bool
}

type QueueImpl struct {
	locker *sync.RWMutex
	slice  []interface{}
	size   uint
}

func NewQueue() Queue {
	q := QueueImpl{
		locker: new(sync.RWMutex),
		slice:  make([]interface{}, 0),
		size:   0,
	}
	return Queue(&q)
}

func (q *QueueImpl) Add(item interface{}) {
	q.locker.Lock()
	defer q.locker.Unlock()
	q.slice = append(q.slice, item)
	q.size++
}

func (q *QueueImpl) Poll() interface{} {
	q.locker.Lock()
	defer q.locker.Unlock()
	if q.size == 0 {
		return nil
	}
	item := q.slice[0]
	q.slice = q.slice[1:]
	q.size--
	return item
}

func (q *QueueImpl) Size() int {
	q.locker.RLock()
	defer q.locker.RUnlock()
	return int(q.size)
}

func (q *QueueImpl) IsEmpty() bool {
	q.locker.RLock()
	defer q.locker.RUnlock()
	return q.size == 0
}
